package org.jackysoft.util;

import org.apache.struts2.convention.SEOActionNameBuilder;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.json.annotations.JSON;
import org.jackysoft.struts2.AbstractAction;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

public class Page implements Cloneable {

	// 当前页码
	private Integer page=0;

	// 总页数
	private Integer total=0;

	// 总记录数
	private Integer records=0;

	//每页条数
	private Integer offset=10;
	
	// 记录实体
	private Iterable<?> rows;
	
	
	////////////////////////////////////////////////////////////
	//for action url

    private Class<? extends AbstractAction> actionClass;
    
    private String method;
	
	private int from=0;

    private	static final SEOActionNameBuilder seoNameBuilder = new SEOActionNameBuilder("true","-");
	
	
	@JSON(serialize=false)
	public int getEnd() {
		if(page==(total-1)){
			//最后一页
			int lst = records%offset;
			return getFrom()+lst;
		}
		return getFrom()+offset;
	}	

	@JSON(serialize=false)
	public int getFrom() {
		from = page*offset;
		return from<0?0:from;
	}

	
	public Integer getPage() {
		return page;
	}

	public void setPage(Integer page) {
		this.page = page;
	}

	public Integer getTotal() {
		return total;
	}
	

	public Integer getRecords() {
		return records;
	}

	public void setRecords(Integer records) {
		this.records = records;
		double drecords = this.records.doubleValue();
		double doffset  = this.offset.doubleValue();
		if(records>0)
			total = new Double(Math.ceil(drecords/doffset)).intValue();
		else
			total = 0;
		if(page>total) page = new Double(total).intValue();
	}

	public Iterable getRows() {
		return rows;
	}

	public void setRows(Iterable rows) {
		this.rows = rows;
	}
	
	@JSON(serialize=false)
	public Integer getOffset() {
		return offset;
	}

	public void setOffset(Integer offset) {
		this.offset = offset;
	}
	
	
	public enum NavType{
		prev,next,page,first,last,info
	}
	
	@JSON(serialize=false)
	public Element getPaginationElement(){
		Document doc = Jsoup.parse("");
		Element div = doc.createElement("div");
		div.addClass("pagination");
		Element ul = doc.createElement("ul");
		div.appendChild(ul);
		Integer cpage = getPage();
        Integer total = getTotal();		
        ul.appendChild(pager(0,false,doc,NavType.first));
        
		if (cpage >= 1) {
			// 可以显示上页按钮
			ul.appendChild(pager(cpage - 1, false, doc, NavType.prev));
		}
		//默认显示10个页码
		Integer end = ((cpage+10)>=total)?total:(cpage+10);
		
		//如果当前页到最后一页数大于所要显示的页码个数10
		//则按照顺序从当前页往后显示10个页码数
	    for(int page = cpage;page<end;page++){
	    	ul.appendChild(pager(page,(page==cpage),doc,NavType.page));
	    }		
		
		if (cpage < (total-1)) {
            ul.appendChild(pager(cpage+1,false,doc,NavType.next));
		}
		
		 ul.appendChild(pager(getTotal()-1,false,doc,NavType.last));
		 ul.appendChild(pager(cpage,false,doc,NavType.info));
		 
		return div;
	}
	
	@JSON(serialize=false)
	public String getPagination() {

		return getPaginationElement().outerHtml();

	}

	
	/**
	 * @param page 页码
	 * @param actived 
	 * 
	 * */
	Element pager(Integer page, boolean actived, Document doc, NavType navType) {

		page = page < 0 ? 0 : page;
		Element li = doc.createElement("li");
		Element a = doc.createElement("a");
		a.attr("href", "javascript:void(0);");
		a.attr("page", page + "");
		a.attr("link",getAction(page));
		if (actived){
			li.addClass("active");
		    a.addClass("noclick");
		}
		switch(navType){
			case prev:
				a.text("上页");
				li.appendChild(a);
				break;
			case next:
				a.text("下页");
				li.appendChild(a);
				break;
			case page:
				a.text(page+1+"");
				
				li.appendChild(a);
				break;
			case first:
				a.text("首页");
				
				li.appendChild(a);
				break;
			case last:
			    a.text("末页");
			    li.appendChild(a);
			    break;
			case info:
				String str = String.format("第  %s/%s 页 , 共  %s 条记录,当前显示从 %s 到 %s 条", getPage()+1,getTotal(),getRecords(),getFrom(),getEnd());
				Element span = li.appendElement("span");
		        span.text(str);
				
				break;
		}
		
		
		return li;
	}

	@Override
	public Page clone() {
		
		Object obj = null;
		try {
			obj = super.clone();
		} catch (CloneNotSupportedException e) {
			
		}
		return (Page) obj;
	}

	
	public void setActionClass(Class<? extends AbstractAction> actionClass) {
		this.actionClass = actionClass;
	}

	public void setMethod(String method) {
		this.method = method;
	}
	
	
	

	public String getAction(int page) {
		String actionUrl="";
		Namespace ns = AnnotationUtil.getAnnotation(this.actionClass, Namespace.class);
		if(ns==null)return "";
		String nps  = ns.value().substring(1);
		String aname = seoNameBuilder.build(this.actionClass.getSimpleName());
	    if(nps.lastIndexOf('/')==(nps.length()-1)){
	    	actionUrl = String.format("%s%s!%s?page=%s&rows=%s&query.state=PAGE", nps,aname,method,page,getOffset());
	    }else{
	    	actionUrl = String.format("%s/%s!%s?page=%s&rows=%s&query.state=PAGE", nps,aname,method,page,getOffset());
	    }
		return actionUrl;
	}
	
	
}
